package com.example.project10;

import android.app.AlertDialog;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import java.util.ArrayList;

/**
 * HomeFragment 是应用的主页界面，它遵循 MVVM 架构模式。
 * 作为 View 层，它负责展示UI、响应用户交互，并通过观察 SharedViewModel 中的 LiveData 来更新界面。
 * 它的核心职责是显示一个基于用户兴趣的推荐列表，并支持下拉刷新和长按删除功能。
 */
public class HomeFragment extends Fragment {

    // --- UI 控件成员变量 ---
    private TextView tvRecommendation; // 用于显示个性化推荐语的文本视图
    private RecyclerView rvRecommendations; // 用于显示推荐内容列表的核心控件
    private SwipeRefreshLayout swipeRefreshLayout; // 支持下拉刷新功能的外层容器

    // --- 架构组件成员变量 ---
    private SharedViewModel sharedViewModel; // ViewModel，负责管理此Fragment的UI数据和业务逻辑
    private RecommendationAdapter adapter; // RecyclerView 的适配器，负责将数据绑定到列表项视图

    /**
     * Fragment 生命周期方法：创建视图（View）。
     * 在这个阶段，系统会调用此方法来加载Fragment的布局文件，并将其转换为一个View对象。
     *
     * @param inflater           用于加载XML布局文件的LayoutInflater对象
     * @param container          父ViewGroup，Fragment的UI将会被插入到这里
     * @param savedInstanceState 如果Fragment是从之前的状态恢复，这里会包含保存的数据
     * @return 返回创建好的Fragment根视图
     */
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        // 1. 加载 fragment_home.xml 布局文件，生成视图对象
        View view = inflater.inflate(R.layout.fragment_home, container, false);

        // 2. 初始化视图控件，通过 findViewById 将XML中的控件与Java代码中的变量关联起来
        tvRecommendation = view.findViewById(R.id.tv_recommendation);
        rvRecommendations = view.findViewById(R.id.rv_recommendations);
        swipeRefreshLayout = view.findViewById(R.id.swipe_refresh_layout);

        // 3. 返回最终的视图
        return view;
    }

    /**
     * Fragment 生命周期方法：视图（View）已经创建完成。
     * 这个方法在 onCreateView() 之后立即调用，确保了所有的视图都已经初始化。
     * 这是执行与视图相关的逻辑设置，如设置监听器、观察LiveData等的最佳位置。
     *
     * @param view                 由onCreateView()返回的根视图
     * @param savedInstanceState 如果Fragment是从之前的状态恢复，这里会包含保存的数据
     */
    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        // 关键步骤1: 获取 ViewModel 实例。
        // 使用 ViewModelProvider(requireActivity()) 来获取一个与宿主Activity生命周期绑定的ViewModel。
        // 这意味着这个ViewModel实例可以在该Activity下的所有Fragment之间共享，是实现Fragment间通信的推荐方式。
        sharedViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);

        // 关键步骤2: 设置 RecyclerView，进行列表相关的初始化
        setupRecyclerView();

        // 关键步骤3: 设置下拉刷新功能
        setupSwipeRefresh();

        // 关键步骤4: 观察 ViewModel 中的 LiveData 数据变化，这是MVVM模式的核心
        observeData();

        // 关键步骤5: 通知 ViewModel 开始加载初始数据。
        // Fragment只负责发出指令，不关心具体如何加载。
        sharedViewModel.loadRecommendations();
    }

    /**
     * 辅助方法：初始化和配置 RecyclerView。
     */
    private void setupRecyclerView() {
        // 1. 设置布局管理器（LayoutManager），这里使用线性布局，实现垂直滚动的列表
        rvRecommendations.setLayoutManager(new LinearLayoutManager(getContext()));
        // 2. 创建适配器（Adapter）实例，并传入一个空的初始列表
        adapter = new RecommendationAdapter(getContext(), new ArrayList<>());

        // 3. 为适配器设置长按监听器。
        // 这里使用了Lambda表达式，将长按事件的处理逻辑保留在Fragment中，而不是Adapter里。
        // 这遵循了"关注点分离"原则：Adapter负责视图展示和事件传递，Fragment负责业务逻辑处理。
        adapter.setOnItemLongClickListener(position -> {
            // 当长按事件发生时，调用方法显示删除确认对话框
            showDeleteConfirmDialog(position);
        });

        // 4. 将适配器设置给 RecyclerView，完成数据和视图的连接
        rvRecommendations.setAdapter(adapter);
    }

    /**
     * 辅助方法：初始化和配置 SwipeRefreshLayout。
     */
    private void setupSwipeRefresh() {
        // 安全检查，确保 swipeRefreshLayout 控件已成功初始化
        if (swipeRefreshLayout != null) {
            // 1. 设置下拉刷新事件的监听器
            swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    // 当用户执行下拉操作时，此方法会被调用。
                    // Fragment不直接处理数据刷新逻辑，而是通知ViewModel去执行。
                    if (sharedViewModel != null) {
                        sharedViewModel.refreshRecommendations();
                    }
                }
            });

            // 2. (可选) 设置刷新动画的颜色方案，提升用户体验
            swipeRefreshLayout.setColorSchemeColors(
                    0xFF2196F3, // 蓝色
                    0xFF4CAF50, // 绿色
                    0xFFFF9800, // 橙色
                    0xFFE91E63  // 红色
            );
        }
    }

    /**
     * 辅助方法：观察 ViewModel 中的 LiveData 对象。
     * 这是实现数据驱动UI（Data-Driven UI）的关键。
     */
    private void observeData() {
        // 安全检查
        if (sharedViewModel == null) return;

        // 1. 观察兴趣数据（currentInterest）的变化
        // getViewLifecycleOwner()确保了观察的生命周期与Fragment视图的生命周期绑定，能自动处理订阅和取消订阅，防止内存泄漏。
        sharedViewModel.getCurrentInterest().observe(getViewLifecycleOwner(), interest -> {
            // 当兴趣数据发生变化时，这个Lambda回调会自动执行。
            if (tvRecommendation != null) {
                // 更新UI，显示包含最新兴趣的推荐语。
                tvRecommendation.setText("根据您的兴趣【" + interest + "】，推荐内容如下");
            }
        });

        // 2. 观察推荐列表数据（recommendationList）的变化
        sharedViewModel.getRecommendationList().observe(getViewLifecycleOwner(), items -> {
            // 当列表数据（如初次加载、刷新、删除项后）发生变化时，此回调执行。
            if (items != null && adapter != null) {
                // 调用适配器的方法来更新列表显示。
                adapter.updateItems(items);
            }
        });

        // 3. 观察刷新状态（isRefreshing）的变化
        sharedViewModel.getIsRefreshing().observe(getViewLifecycleOwner(), isRefreshing -> {
            // 这个LiveData用于控制下拉刷新动画的显示和隐藏。
            // ViewModel负责在开始加载数据时设为true，加载结束后设为false。
            // Fragment只负责根据这个状态来更新UI，实现了UI状态和业务逻辑的解耦。
            if (swipeRefreshLayout != null && isRefreshing != null) {
                swipeRefreshLayout.setRefreshing(isRefreshing);
            }
        });
    }

    /**
     * 辅助方法：显示一个用于确认删除操作的对话框。
     * @param position 要删除的列表项的位置
     */
    private void showDeleteConfirmDialog(int position) {
        // 使用AlertDialog.Builder来构建对话框
        new AlertDialog.Builder(getContext())
                .setTitle("删除确认") // 设置标题
                .setMessage("您确定要删除这个推荐项吗？") // 设置提示信息
                // 设置"确定"按钮及其点击事件
                .setPositiveButton("删除", (dialog, which) -> {
                    // 用户确认删除后，通知ViewModel执行删除操作，并传入要删除项的位置
                    sharedViewModel.removeRecommendationItem(position);
                })
                // 设置"取消"按钮，点击后对话框自动消失，无需额外操作（传入null即可）
                .setNegativeButton("取消", null)
                .show(); // 创建并显示对话框
    }
}